package com.wangyadong.hobby.schedule.jobtask.javasync.Observerable;

/**
 * <p>
 *
 * @author <714037465@qq.com>
 * @since 2018/11/1512:50
 **/
public final class ObserverableThread<T> extends Thread implements Observerable {

    private final TaskLife<T> life;
    private final Task<T> tTask;
    private Cycle cycle;

    public ObserverableThread(Task<T> tTask) {
        this(new TaskLife.EmptyTaskLife(), tTask);
    }

    public ObserverableThread(TaskLife<T> life, Task<T> tTask) {
        this.life = life;
        this.tTask = tTask;
    }

    @Override
    public final void run() {
        this.update(Cycle.Start, null, null);
        try {
            T call = this.tTask.call();
            this.update(Cycle.Finsh, call, null);
        } catch (Exception e) {
            this.update(Cycle.Error, null, e);
        }
    }

    @Override
    public Cycle getVale() {
        return cycle;
    }

    @Override
    public void interrupte() {

    }

    private void update(Cycle cycle, T result, Exception e) {
        this.cycle = cycle;
        if (life == null) {
            return;
        }
        try {
            switch (cycle) {
                case Start:
                    this.life.onStart(currentThread());
                    break;
                case Running:
                    this.life.onRunning(currentThread());
                    break;
                case Finsh:
                    this.life.onFinsh(currentThread(), result);
                    break;
                case Error:
                    this.life.onError(currentThread(), e);
                    break;
            }
        } catch (Exception ex) {
            if (cycle == Cycle.Error) {
                throw ex;
            }
        }

    }
}
